package com.gtd.jdo

import javax.jdo.*

import com.google.appengine.api.datastore.KeyFactory

import com.gtd.util.SpringApplicationContext


/**
 * This class is used for manipulating jdo objects
 *
 * More effective try/catch
 *
 *
 * @author  hoatle
 *          hoatlevan at gmail dot com
 * @since   1.0
 * created: Jul 5, 2009
 */
final class JdoUtil {
	static getPersistenceManager() throws Exception {
      return (PersistenceManager) SpringApplicationContext.getBean("persistenceManager")
  }
  
  /**
   * GetObjectById
   *
   * @param clazz Class
   * @param id String
   * @return clazz object
   */
  static getObjectById(Class clazz, String id) throws Exception {
    def pm, k, o, msg
    pm = getPersistenceManager()
    try {
      k = KeyFactory.createKey(clazz.simpleName, id.toInteger())
      //Retrieve object
      try {
        o = pm.getObjectById(clazz, k)
      } catch(Exception e) {
        msg = "Could not get ${clazz.simpleName} object"
        throw new Exception(msg)
      }
    } catch(Exception e) {
      msg = "Problem with id = ${id}"
      throw new Exception(msg)
    }
    return o
  }

  /**
   * makePersitent for an object
   *
   * @param o Object
   * @return saved Object
   * @since   1.0
   */
  static makePersistent(o) throws Exception {
    def pm, saved, msg
    pm = getPersistenceManager()
    if (o.validate()) {
      try {
        saved = pm.makePersistent(o)
      }catch(Exception e) {
        msg = "Could not save ${o.class.simpleName} object."
        throw new Exception(msg)
        //println e.printStackTrace()

      }
    } else {
      List e = new ArrayList()
      e.add("${o.class.simpleName} is not successfully validated.")
      o.errors.allErrors.each({
          e.add(it)
      })
      msg = e
      throw new Exception(msg)
    }
    return saved
  }
  /**
   * deletePersistent
   *
   * @param o Object
   * @return deleted Boolean
   */
  static deletePersistent(o) throws Exception {
    def pm, msg
    pm = getPersistenceManager()
    try {
      pm.deletePersistent(o)
      msg = "${o.class.simpleName} object was successfully deleted."
      return true
    } catch(Exception e) {
      msg = "Could not delete ${o.class.simpleName} object"
      throw new Exception(msg)
    }
  }

  /**
   * getList: Get the list of object by range
   *
   * @param page Integer
   * @itemsPerPage Integer
   * @return oList List<clazz> or null
   * @since 1.0
   */
  static getList(Class clazz, page, itemsPerPage) throws Exception {
    def pm, msg, oList
    //If not specified, params.page = 1
    if (!page) {
      page = 1
    }
    //If not specified, params.itemsPerPage = 15
    if (!itemsPerPage) {
      itemsPerPage = 15
    }
    try {
      page = page.toInteger()
      itemsPerPage = itemsPerPage.toInteger()
    } catch(Exception e) {
      msg = "Problem with page=${page} or itemsPerPage=${itemsPerPage}"
      throw new Exception(msg)
    }


    pm = getPersistenceManager()

    def query = pm.newQuery(clazz)
    def startRange = (page - 1) * itemsPerPage
    query.setRange(startRange, itemsPerPage)

    try {
      oList = query.execute()
    } catch(Exception e) {
      msg = "Could not load ${clazz.simpleName} list."
      throw new Exception(msg)
    }
    if (oList.size() > 0) {
      msg = [
        oList: oList,
        page: page,
        itemsPerPage: itemsPerPage,
        total: "?"
      ]
      return msg
    } else {
      //No data yet
      msg = []
      return msg
    }
  }
}